今天我們要來把昨天沒說完的運算子給說完,因此今天的主題是:**邏輯運算子(Logical operators)**以及 條件(三元)運算子(Conditional (ternary) operator)
我們先來看一下MDN幫我們整理過的表格:
好像沒有很清楚,我們一樣用程式碼再來看一次:
// &&
var a1 = true && true; // 回傳 true
var a2 = true && false; // 回傳 false
var a3 = false && true; // 回傳 false
// ||
var o1 = true || true; // 回傳 true
var o2 = false || true; // 回傳 true
var o3 = true || false; // 回傳 true
// !
var n1 = !true; // 回傳 false
var n2 = !false; // 回傳 true
var n3 = !"Cat"; // 回傳 false
因此我是這麼理解的:
在一開始我們最常會在if
裡面看到這些東西,例如:
const isLogged = true;
const isAdmin = true;
if (isLogged && isAdmin) {
console.log("You have admin privileges");
} else {
console.log("You do not have admin privileges");
}
但大家都知道,工程師很懶惰的 效率是現在大家最重視的事情,像這樣子每次都要寫if eles
的判斷實在是浪費效率,因此有了短路解析(Short-circuit evaluation),也有人說是短路求值。
短路解析(Short-circuit evaluation)是指一種方法,它是指用||
或&&
來寫比起if
判斷式更短更簡潔的判斷式。
接下來我們就來對兩個(&& 和 ||)來做解說:
使用 &&
運算符時,第一個表達式為 false
,則整個表達式一定為 false
,JavaScript 會立即停止執行後續的表達式,因此後續的表達式不會被執行。
我們來看範例,會比較清楚:
const data = {
firstName: "Jeff",
lastName: "Wang",
address: {
street: "111 Main St.",
city: "New York",
state: "NY",
},
};
data && console.log(data)
因此當你今天有一個必須要“第一個條件成立,才會繼續執行後面“的程式碼就可以考慮這樣的方式。
使用 ||
運算子時,第一個表達式為 true
,則整個表達式一定為 true
,JavaScript 會立即停止執行後續的表達式,因此後續的表達式不會被執行。
一樣先看範例:
const data = response.json();
console.log(data.message || "Something went wrong");
這是一段我們跟資料庫要資料的片段程式碼,他的意思是如果data.message
裡面有資料就幫我印出來,但如果沒有就幫我印出"Something went wrong"。
或者我們也可以用撈localStorage
的資料來做示範:
var data = localStorage.getItem('todo');
if (data) {
data = JSON.parse(data);
} else {
data = [];
}
改成Short-circuit evaluation 後:
var data = JSON.parse(localStorage.getItem('todo'))||[];
這個方式是我們在撈資料時非常常用的方式,可以解省非常多的時間。
這是在MDN查找資料時突然看到的,才想起來之前有遇到過,但真的遇到不多就忘記了。
自己了解不多,所以如果有錯再請大家指教。
可選串連運算子(Optional chaining ) (?.)
當串連物件裡面的參照或方法可能是undefined
或 null
時,可選串連運算子提供簡單的方法去存取這些串連物件下的值。
我們用下面這個案例做說明:
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah',
},
};
// 狀況1
const dogName = adventurer.dog.name;
console.log(dogName);
// TypeError: Cannot read properties of undefined (reading 'name')
// 狀況2
const dogName = adventurer.dog?.name;
console.log(dogName); // undefined
當如果今天是狀況1時,我們直接使用 adventurer.dog.name
,但是因為 dog
物件不存在,所以這裡會拋出錯誤,報告說無法讀取未定義的屬性。
當在狀況2時,我們使用了可選鏈運算符 ?.
,這表示如果 dog
物件不存在,直接返回 undefined
,而不會出現錯誤。因此,dogName
的值就會是為 undefined
。
為什麼我們會需要這個呢?沒有這個object 出現錯誤不是很正常嗎?
這是因為在很多狀況下,我們更希望得到的是 undefined
(表示沒有dog
屬性)而不是一個錯誤。
空值合併運算子(Nullish coalescing operator) (??)
??
的用法與||
的用法非常相似,都能用作預設值,差異之處是:
??
會返回第一個defined
的值||
會返回第一個truthy
的值那什麼是defined
的值呢?
當一個值,如果它不是null
也不是undefined
,那它就會是defined
,意思是一個已經定義的值。我們看一下案例,來加深一下記憶:
const foo = null ?? 'default string';
console.log(foo);
// Expected output: "default string"
const baz = 0 ?? 42;
console.log(baz);
// Expected output: 0
條件運算子是 JavaScript 唯一用到三個運算元的運算子,應此也稱三元運算子。它的格式通常如下:
condition ? exprIfTrue : exprIfFalse
其中,condition
是一個布林值的表達式,exprIfTrue
和 exprIfFalse
是兩個可以求值的表達式。三元運算符根據 condition
的布林值來選擇執行哪一個表達式,如果 condition
為真,則執行 exprIfTrue
,否則執行 exprIfFalse
。
另外除了 false
之外,可能的 falsy
(偽值) 表達式還包括:null
、NaN
、0
、空字符串 ""
和 undefined
。
如果條件是這些值之一,則條件表達式的結果將是執行 exprIfFalse
表達式的結果。
舉個例子:
var age = 26;
var beverage = age >= 21 ? "Beer" : "Juice";
console.log(beverage); // "Beer"
用這樣的寫法我們就不用寫if … else的判斷式了,可以解省非常多的時間。
不知不覺又寫的有點多,但重新再學一次真的感觸很多,繼續加油!還剩下19天。